<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PHP&JS前后端数据加解密</title>
    <script src="./assets/jquery.min.js"></script>
    <script src="./assets/crypto-js/crypto-js.js"></script>
    <script src="./assets/jsencrypt/bin/jsencrypt.min.js"></script>
    <style type="text/css">

        .demo-tab {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .demo-tab .demo-tab-item {
            flex: 1;
            text-align: center;
            padding: 15px;
            border: 1px solid #eee;
        }

        .demo-tab .demo-tab-item:hover,
        .demo-tab .demo-tab-item.active {
            border-color: #8a8a8a;
        }

        .demo {
            display: none;
        }

        .demo.active {
            display: block;
        }

        .demo h1 {
            color: red;
        }

        .demo-item-container {
            display: flex;
        }

        .demo-control {
            margin: 0 15px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
        }

        .demo-control button {
            margin: 0 15px;
        }

        .demo-aes-rsa .demo-item-container {
            display: flex;
            flex-direction: column;
        }

        .demo-textarea-items {
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .demo-aes-rsa .demo-control button {
            margin: 15px 0;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="demo-tab">
        <div class="demo-tab-item active" data-for="aes">AES</div>
        <div class="demo-tab-item" data-for="rsa">RSA</div>
        <div class="demo-tab-item" data-for="aes-rsa">AES+RSA</div>
    </div>
    <div class="demo demo-aes active">
        <h1>AES</h1>
        <div class="demo-item">
            <h2>JS加解密数据</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="aes_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_js_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="aes_js_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_js_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="aes_js_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP加解密数据</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="aes_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_php_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="aes_php_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_php_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="aes_php_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>JS加密PHP解密数据</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="aes_js_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_js_php_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="aes_js_php_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_js_php_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="aes_js_php_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP加密JS解密数据</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="aes_php_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_php_js_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="aes_php_js_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_php_js_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="aes_php_js_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
    </div>
    <div class="demo demo-rsa">
        <h1>RSA</h1>
        <div class="demo-item">
            <h2>JS加解密数据（客户端公钥加密，客户端私钥解密）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_js_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="rsa_js_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_js_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="rsa_js_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>JS数据签名/验签（客户端私钥签名，客户端公钥验签）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_sign_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_js_generate">签名</button>
                </div>
                <div class="demo-control">
                    <span>签名</span>
                    <textarea id="rsa_sign_js_sign" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_js_verify">验签</button>
                </div>
                <div class="demo-control">
                    <span>验签结果</span>
                    <span id="rsa_sign_js_verify"></span>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP加解密数据（服务端公钥加密，服务端私钥解密）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_php_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="rsa_php_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_php_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="rsa_php_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP数据签名/验签（服务端私钥签名，服务端公钥验签）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_sign_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_php_generate">签名</button>
                </div>
                <div class="demo-control">
                    <span>签名</span>
                    <textarea id="rsa_sign_php_sign" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_php_verify">验签</button>
                </div>
                <div class="demo-control">
                    <span>验签结果</span>
                    <span id="rsa_sign_php_verify"></span>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>JS加密PHP解密数据（客户端使用服务端公钥加密，服务端私钥加密）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_js_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_js_php_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="rsa_js_php_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_js_php_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="rsa_js_php_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP加密JS解密数据（服务端使用客户端公钥加密，客户端私钥加密）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_php_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_php_js_encrypt">加密</button>
                </div>
                <div class="demo-control">
                    <span>密文</span>
                    <textarea id="rsa_php_js_encrypted" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_php_js_decrypt">解密</button>
                </div>
                <div class="demo-control">
                    <span>解密结果</span>
                    <textarea id="rsa_php_js_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>JS数据签名PHP验签（客户端私钥签名，服务端使用客户端公钥验签）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_sign_js_php_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_js_php_generate">签名</button>
                </div>
                <div class="demo-control">
                    <span>签名</span>
                    <textarea id="rsa_sign_js_php_sign" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_js_php_verify">验签</button>
                </div>
                <div class="demo-control">
                    <span>验签结果</span>
                    <span id="rsa_sign_js_php_verify"></span>
                </div>
            </div>
        </div>
        <div class="demo-item">
            <h2>PHP数据签名JS验签（服务端私钥签名，客户端使用服务端公钥验签）</h2>
            <div class="demo-item-container">
                <div class="demo-control">
                    <span>数据</span>
                    <textarea id="rsa_sign_php_js_data" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_php_js_generate">签名</button>
                </div>
                <div class="demo-control">
                    <span>签名</span>
                    <textarea id="rsa_sign_php_js_sign" cols="30" rows="10"></textarea>
                </div>
                <div class="demo-control">
                    <button id="btn_rsa_sign_php_js_verify">验签</button>
                </div>
                <div class="demo-control">
                    <span>验签结果</span>
                    <span id="rsa_sign_php_js_verify"></span>
                </div>
            </div>
        </div>
    </div>
    <div class="demo demo-aes-rsa" id="">
        <h1>AES+RSA</h1>
        <div class="demo-desc">
            客户端请求数据使用aes加密数据，aes的key和iv再使用服务端公钥进行rsa加密；<br>
            服务端拿到数据，先使用服务端私钥解密aes的key和iv，再使用aes解密数据；<br>
            服务端拿到解密数据后，进行业务处理，对需要返回给客户端的数据进行aes加密处理，aes的key和iv用服务端私钥进行rsa签名，将签名和数据一起返回给客户端；<br>
            客户端拿到响应数据和签名后，先使用服务端公钥对服务端响应的aes的key和iv进行rsa验签，验签通过后再使用aes解密数据，最后将解密的响应数据展现出来。<br>
        </div>
        <div class="demo-item">
            <div class="demo-item-container">
                <div class="demo-textarea-items">
                    <div class="demo-control">
                        <span>客户端数据</span>
                        <textarea id="aes_rsa_client_data" cols="30" rows="10"></textarea>
                    </div>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_rsa_client_aes_encrypt">客户端AES加密</button>
                </div>
                <div class="demo-textarea-items">
                    <div class="demo-control">
                        <span>客户端AES key</span>
                        <textarea id="aes_rsa_client_aes_key" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>客户端AES iv</span>
                        <textarea id="aes_rsa_client_aes_iv" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>客户端AES密文</span>
                        <textarea id="aes_rsa_client_aes_encrypted" cols="30" rows="10"></textarea>
                    </div>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_rsa_client_rsa_encrypt_aes_key_iv">客户端AES的key和iv进行RSA加密</button>
                </div>
                <div class="demo-textarea-items">
                    <div class="demo-control">
                        <span>客户端RSA加密的AES key</span>
                        <textarea id="aes_rsa_client_rsa_aes_key_encrypted" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>客户端RSA加密的AES iv</span>
                        <textarea id="aes_rsa_client_rsa_aes_iv_encrypted" cols="30" rows="10"></textarea>
                    </div>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_rsa_client_request">客户端向服务端发出请求</button>
                </div>
                <div class="demo-textarea-items">
                    <div class="demo-control">
                        <span>服务端响应的AES key</span>
                        <textarea id="aes_rsa_server_response_aes_key" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>服务端响应的AES key的RSA签名sign</span>
                        <textarea id="aes_rsa_server_response_aes_key_rsa_sign" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>服务端响应的AES iv</span>
                        <textarea id="aes_rsa_server_response_aes_iv" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>服务端响应的AES iv的RSA签名sign</span>
                        <textarea id="aes_rsa_server_response_aes_iv_rsa_sign" cols="30" rows="10"></textarea>
                    </div>
                    <div class="demo-control">
                        <span>服务端响应的AES密文</span>
                        <textarea id="aes_rsa_server_response_aes_encrypted" cols="30" rows="10"></textarea>
                    </div>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_rsa_server_response_aes_key_iv_rsa_sign_verify">客户端对服务端响应的AES的key和iv进行RSA验签
                    </button>
                </div>
                <div class="demo-textarea-items">
                    <div class="demo-control">
                        <span>服务端响应的AES key验签结果</span>
                        <span id="aes_rsa_server_response_aes_key_rsa_sign_verify"></span>
                    </div>
                    <div class="demo-control">
                        <span>服务端响应的AES iv验签结果</span>
                        <span id="aes_rsa_server_response_aes_iv_rsa_sign_verify"></span>
                    </div>
                </div>
                <div class="demo-control">
                    <button id="btn_aes_rsa_server_response_aes_decrypt">对服务端响应的AES密文进行解密</button>
                </div>
                <div class="demo-control">
                    <span>AES解密结果</span>
                    <textarea id="aes_rsa_server_response_aes_decrypted" cols="30" rows="10"></textarea>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="./lib/key.js"></script>
<!-- aes需包含crypto-js.js -->
<script src="./lib/aes.js"></script>
<!-- rsa需包含crypto-js.js、jsencrypt.js -->
<script src="./lib/rsa.js"></script>
<script type="text/javascript">
    ((win, doc, $) => {

        class Base {

            request(url, data) {
                return new Promise((resolve, reject) => {
                    $.ajax({
                        url: url,
                        type: "post",
                        data: data || null,
                        cache: false,
                        dataType: "json",
                        success: function (res) {
                            resolve(res);
                        },
                        error: function (err) {
                            reject(err);
                        }
                    });
                });
            }

            randStr(len = 32) {
                let strPol = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
                let strPolLen = strPol.length;
                let str = "";
                for (let i = 0; i < len; i++) str += strPol.charAt(Math.floor(Math.random() * strPolLen));
                return str
            }

            generateAESKey() {
                return this.randStr(16);
            }

            generateAESIv() {
                return this.randStr(16);
            }

        }

        class AESJS extends Base {

            get aes() {
                return this._aes;
            }

            constructor(key, iv) {
                super();
                this._aes = new AES(key, iv);
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#aes_js_data");
                that.encryptedEl = $("#aes_js_encrypted");
                that.decryptedEl = $("#aes_js_decrypted");
                that.btnEncryptEl = $("#btn_aes_js_encrypt");
                that.btnDecryptEl = $("#btn_aes_js_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let encrypted = that.aes.encrypt(data);
                    that.encryptedEl.val(encrypted);
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let decrypted = that.aes.decrypt(encrypted);
                    that.decryptedEl.val(decrypted);
                });

            }

        }

        class AESPHP extends Base {

            get key() {
                return this._key;
            }

            get iv() {
                return this._iv;
            }

            constructor(key, iv) {
                super();
                this._key = key;
                this._iv = iv;
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#aes_php_data");
                that.encryptedEl = $("#aes_php_encrypted");
                that.decryptedEl = $("#aes_php_decrypted");
                that.btnEncryptEl = $("#btn_aes_php_encrypt");
                that.btnDecryptEl = $("#btn_aes_php_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "encrypt",
                        key: that.key,
                        iv: that.iv,
                        data: data
                    };
                    that.request("/server/index.php?route=aes", requestData).then(res => {
                        that.encryptedEl.val(res.data);
                    });
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let requestData = {
                        type: "decrypt",
                        key: that.key,
                        iv: that.iv,
                        data: encrypted
                    };
                    that.request("/server/index.php?route=aes", requestData).then(res => {
                        that.decryptedEl.val(res.data);
                    });
                });

            }

        }

        class AESJSEncrytPHPDecrypt extends Base {

            get key() {
                return this._key;
            }

            get iv() {
                return this._iv;
            }

            get aes() {
                return this._aes;
            }

            constructor(key, iv) {
                super();
                this._key = key;
                this._iv = iv;
                this._aes = new AES(key, iv);
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#aes_js_php_data");
                that.encryptedEl = $("#aes_js_php_encrypted");
                that.decryptedEl = $("#aes_js_php_decrypted");
                that.btnEncryptEl = $("#btn_aes_js_php_encrypt");
                that.btnDecryptEl = $("#btn_aes_js_php_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let encrypted = that.aes.encrypt(data);
                    that.encryptedEl.val(encrypted);
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let requestData = {
                        type: "decrypt",
                        key: that.key,
                        iv: that.iv,
                        data: encrypted
                    };
                    that.request("/server/index.php?route=aes", requestData).then(res => {
                        that.decryptedEl.val(res.data);
                    });
                });

            }

        }

        class AESPHPEncrytJSDecrypt extends Base {

            get key() {
                return this._key;
            }

            get iv() {
                return this._iv;
            }

            get aes() {
                return this._aes;
            }

            constructor(key, iv) {
                super();
                this._key = key;
                this._iv = iv;
                this._aes = new AES(key, iv);
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#aes_php_js_data");
                that.encryptedEl = $("#aes_php_js_encrypted");
                that.decryptedEl = $("#aes_php_js_decrypted");
                that.btnEncryptEl = $("#btn_aes_php_js_encrypt");
                that.btnDecryptEl = $("#btn_aes_php_js_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "encrypt",
                        key: that.key,
                        iv: that.iv,
                        data: data
                    };
                    that.request("/server/index.php?route=aes", requestData).then(res => {
                        that.encryptedEl.val(res.data);
                    });
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let decrypted = that.aes.decrypt(encrypted);
                    that.decryptedEl.val(decrypted);
                });

            }

        }

        class RSAJS extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_js_data");
                that.encryptedEl = $("#rsa_js_encrypted");
                that.decryptedEl = $("#rsa_js_decrypted");
                that.btnEncryptEl = $("#btn_rsa_js_encrypt");
                that.btnDecryptEl = $("#btn_rsa_js_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let encrypted = that.rsa.encrypt(data, KEY.clientPublicKey);
                    that.encryptedEl.val(encrypted);
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let decrypted = that.rsa.decrypt(encrypted, KEY.clientPrivateKey);
                    that.decryptedEl.val(decrypted);
                });

            }

        }

        class RSAJSSign extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.signEl = null;
                this.verifyEl = null;
                this.btnSignEl = null;
                this.btnVerifyEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_sign_js_data");
                that.signEl = $("#rsa_sign_js_sign");
                that.verifyEl = $("#rsa_sign_js_verify");
                that.btnSignEl = $("#btn_rsa_sign_js_generate");
                that.btnVerifyEl = $("#btn_rsa_sign_js_verify");
            }

            setEventBind() {
                let that = this;

                that.btnSignEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let sign = that.rsa.sign(data, KEY.clientPrivateKey);
                    that.signEl.val(sign);
                });

                that.btnVerifyEl.click(function (e) {
                    let data = that.dataEl.val();
                    let sign = that.signEl.val();
                    if (!data || !sign) return;
                    let res = that.rsa.signVerify(data, sign, KEY.clientPublicKey);
                    that.verifyEl.html(res ? "true" : "false");
                });

            }

        }

        class RSAPHP extends Base {

            constructor() {
                super();
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_php_data");
                that.encryptedEl = $("#rsa_php_encrypted");
                that.decryptedEl = $("#rsa_php_decrypted");
                that.btnEncryptEl = $("#btn_rsa_php_encrypt");
                that.btnDecryptEl = $("#btn_rsa_php_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "encrypt",
                        data: data
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.encryptedEl.val(res.data);
                    });
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let requestData = {
                        type: "decrypt",
                        data: encrypted
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.decryptedEl.val(res.data);
                    });
                });

            }

        }

        class RSAPHPSign extends Base {

            constructor() {
                super();
                this.dataEl = null;
                this.signEl = null;
                this.verifyEl = null;
                this.btnSignEl = null;
                this.btnVerifyEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_sign_php_data");
                that.signEl = $("#rsa_sign_php_sign");
                that.verifyEl = $("#rsa_sign_php_verify");
                that.btnSignEl = $("#btn_rsa_sign_php_generate");
                that.btnVerifyEl = $("#btn_rsa_sign_php_verify");
            }

            setEventBind() {
                let that = this;

                that.btnSignEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "sign",
                        data: data
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.signEl.val(res.data);
                    });
                });

                that.btnVerifyEl.click(function (e) {
                    let data = that.dataEl.val();
                    let sign = that.signEl.val();
                    if (!data || !sign) return;
                    let requestData = {
                        type: "signVerify",
                        data: data,
                        sign: sign,
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.verifyEl.html(res.data ? "true" : "false");
                    });
                });

            }

        }

        class RSAJSEncrytPHPDecrypt extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_js_php_data");
                that.encryptedEl = $("#rsa_js_php_encrypted");
                that.decryptedEl = $("#rsa_js_php_decrypted");
                that.btnEncryptEl = $("#btn_rsa_js_php_encrypt");
                that.btnDecryptEl = $("#btn_rsa_js_php_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let encrypted = that.rsa.encrypt(data, KEY.serverPublicKey);
                    that.encryptedEl.val(encrypted);
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let requestData = {
                        type: "decryptByServerPrivateKey",
                        data: encrypted
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.decryptedEl.val(res.data);
                    });
                });

            }

        }

        class RSAPHPEncrytJSDecrypt extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.encryptedEl = null;
                this.decryptedEl = null;
                this.btnEncryptEl = null;
                this.btnDecryptEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_php_js_data");
                that.encryptedEl = $("#rsa_php_js_encrypted");
                that.decryptedEl = $("#rsa_php_js_decrypted");
                that.btnEncryptEl = $("#btn_rsa_php_js_encrypt");
                that.btnDecryptEl = $("#btn_rsa_php_js_decrypt");
            }

            setEventBind() {
                let that = this;

                that.btnEncryptEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "encryptByClientPrivateKey",
                        data: data
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.encryptedEl.val(res.data);
                    });
                });

                that.btnDecryptEl.click(function (e) {
                    let encrypted = that.encryptedEl.val();
                    if (!encrypted) return;
                    let decrypted = that.rsa.decrypt(encrypted, KEY.clientPrivateKey);
                    that.decryptedEl.val(decrypted);
                });

            }

        }

        class RSAJSSignPHPVerify extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.signEl = null;
                this.verifyEl = null;
                this.btnSignEl = null;
                this.btnVerifyEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_sign_js_php_data");
                that.signEl = $("#rsa_sign_js_php_sign");
                that.verifyEl = $("#rsa_sign_js_php_verify");
                that.btnSignEl = $("#btn_rsa_sign_js_php_generate");
                that.btnVerifyEl = $("#btn_rsa_sign_js_php_verify");
            }

            setEventBind() {
                let that = this;

                that.btnSignEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let sign = that.rsa.sign(data, KEY.clientPrivateKey);
                    that.signEl.val(sign);
                });

                that.btnVerifyEl.click(function (e) {
                    let data = that.dataEl.val();
                    let sign = that.signEl.val();
                    if (!data || !sign) return;
                    let requestData = {
                        type: "signVerifyByClientPublicKey",
                        data: data,
                        sign: sign,
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.verifyEl.html(res.data ? "true" : "false");
                    });
                });

            }

        }

        class RSAPHPSignJSVerify extends Base {

            get rsa() {
                return this._rsa;
            }

            constructor() {
                super();
                this._rsa = new RSA();
                this.dataEl = null;
                this.signEl = null;
                this.verifyEl = null;
                this.btnSignEl = null;
                this.btnVerifyEl = null;
                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.dataEl = $("#rsa_sign_php_js_data");
                that.signEl = $("#rsa_sign_php_js_sign");
                that.verifyEl = $("#rsa_sign_php_js_verify");
                that.btnSignEl = $("#btn_rsa_sign_php_js_generate");
                that.btnVerifyEl = $("#btn_rsa_sign_php_js_verify");
            }

            setEventBind() {
                let that = this;

                that.btnSignEl.click(function (e) {
                    let data = that.dataEl.val();
                    if (!data) return;
                    let requestData = {
                        type: "signByServerPrivateKey",
                        data: data
                    };
                    that.request("/server/index.php?route=rsa", requestData).then(res => {
                        that.signEl.val(res.data);
                    });
                });

                that.btnVerifyEl.click(function (e) {
                    let data = that.dataEl.val();
                    let sign = that.signEl.val();
                    if (!data || !sign) return;
                    let res = that.rsa.signVerify(data, sign, KEY.serverPublicKey);
                    that.verifyEl.html(res ? "true" : "false");
                });

            }

        }

        class AESRSA extends Base {

            constructor(key, iv) {
                super();
                // 客户端数据
                this.clientDataEl = null;
                // 客户端AES key
                this.clientAESKeyEL = null;
                // 客户端AES iv
                this.clientAESIvEL = null;
                // 客户端AES 密文
                this.clientAESEncryptedEL = null;
                // 客户端RSA加密的AES key密文
                this.clientRSAAESKeyEncryptedEL = null;
                // 客户端RSA加密的AES iv密文
                this.clientRSAAESIvEncryptedEL = null;
                // 服务端响应的AES key
                this.serverResponseAESKeyEL = null;
                // 服务端响应的AES key的RSA签名
                this.serverResponseAESKeyRSASignEL = null;
                // 服务端响应的AES iv
                this.serverResponseAESIvEL = null;
                // 服务端响应的AES iv的RSA签名
                this.serverResponseAESIvRSASignEL = null;
                // 服务端响应的AES 密文
                this.serverResponseAESEncryptedEL = null;
                // 服务端响应的AES key验签结果
                this.serverResponseAESKeyRSASignVerifyEL = null;
                // 服务端响应的AES iv验签结果
                this.serverResponseAESIvRSASignVerifyEL = null;
                // 服务端响应的AES 密文的解密结果
                this.serverResponseAESDecryptedEL = null;
                // 客户端AES加密按钮
                this.btnClientAESEncryptEl = null;
                // 客户端AES的key和iv进行RSA加密按钮
                this.btnClientRSAEncryptAESKeyIvEl = null;
                // 客户端向服务端发出请求
                this.btnClientRequestEl = null;
                // 客户端对服务端响应的AES的key和iv进行RSA验签按钮
                this.btnServerResponseAESKeyIvRSASignVerifyEl = null;
                // 服务端响应的AES密文进行解密
                this.btnServerResponseAESDecryptEl = null;

                this.init();
            }

            init() {
                let that = this;
                that.initAttr();
                that.setEventBind();
            }

            initAttr() {
                let that = this;
                that.clientDataEl = $("#aes_rsa_client_data");
                that.clientAESKeyEL = $("#aes_rsa_client_aes_key");
                that.clientAESIvEL = $("#aes_rsa_client_aes_iv");
                that.clientAESEncryptedEL = $("#aes_rsa_client_aes_encrypted");
                that.clientRSAAESKeyEncryptedEL = $("#aes_rsa_client_rsa_aes_key_encrypted");
                that.clientRSAAESIvEncryptedEL = $("#aes_rsa_client_rsa_aes_iv_encrypted");
                that.serverResponseAESKeyEL = $("#aes_rsa_server_response_aes_key");
                that.serverResponseAESKeyRSASignEL = $("#aes_rsa_server_response_aes_key_rsa_sign");
                that.serverResponseAESIvEL = $("#aes_rsa_server_response_aes_iv");
                that.serverResponseAESIvRSASignEL = $("#aes_rsa_server_response_aes_iv_rsa_sign");
                that.serverResponseAESEncryptedEl = $("#aes_rsa_server_response_aes_encrypted");
                that.serverResponseAESKeyRSASignVerifyEL = $("#aes_rsa_server_response_aes_key_rsa_sign_verify");
                that.serverResponseAESIvRSASignVerifyEL = $("#aes_rsa_server_response_aes_iv_rsa_sign_verify");
                that.serverResponseAESDecryptedEL = $("#aes_rsa_server_response_aes_decrypted");
                that.btnClientAESEncryptEl = $("#btn_aes_rsa_client_aes_encrypt");
                that.btnClientRSAEncryptAESKeyIvEl = $("#btn_aes_rsa_client_rsa_encrypt_aes_key_iv");
                that.btnClientRequestEl = $("#btn_aes_rsa_client_request");
                that.btnServerResponseAESKeyIvRSASignVerifyEl = $("#btn_aes_rsa_server_response_aes_key_iv_rsa_sign_verify");
                that.btnServerResponseAESDecryptEl = $("#btn_aes_rsa_server_response_aes_decrypt");

            }

            setEventBind() {
                let that = this;

                // 客户端AES加密
                that.btnClientAESEncryptEl.click(function (e) {
                    let data = that.clientDataEl.val();
                    if (!data) return;
                    let key = that.generateAESKey();
                    let iv = that.generateAESIv();
                    let aes = new AES(key, iv);
                    let encrypted = aes.encrypt(data);
                    that.clientAESKeyEL.val(key);
                    that.clientAESIvEL.val(iv);
                    that.clientAESEncryptedEL.val(encrypted);
                });

                // 客户端AES的key和iv进行RSA加密
                that.btnClientRSAEncryptAESKeyIvEl.click(function (e) {
                    let key = that.clientAESKeyEL.val();
                    let iv = that.clientAESIvEL.val();
                    if (!key || !iv) return;
                    let rsa = new RSA();
                    let keyEncrypted = rsa.encrypt(key, KEY.serverPublicKey);
                    that.clientRSAAESKeyEncryptedEL.val(keyEncrypted);
                    let ivEncrypted = rsa.encrypt(iv, KEY.serverPublicKey);
                    that.clientRSAAESIvEncryptedEL.val(ivEncrypted);
                });

                // 客户端向服务端发出请求
                that.btnClientRequestEl.click(function (e) {
                    let key = that.clientRSAAESKeyEncryptedEL.val();
                    let iv = that.clientRSAAESIvEncryptedEL.val();
                    let data = that.clientAESEncryptedEL.val();
                    if (!key || !iv || !data) return;
                    let requestData = {
                        aesKey: key,
                        aesIv: iv,
                        aesData: data
                    };
                    that.request("/server/index.php?route=aes_rsa", requestData).then(res => {
                        that.serverResponseAESKeyEL.val(res.data.aesKey);
                        that.serverResponseAESKeyRSASignEL.val(res.data.aesKeyRsaSign);
                        that.serverResponseAESIvEL.val(res.data.aesIv);
                        that.serverResponseAESIvRSASignEL.val(res.data.aesIvRsaSign);
                        that.serverResponseAESEncryptedEl.val(res.data.aesData);
                    });

                });

                // 客户端对服务端响应的AES的key和iv进行RSA验签
                that.btnServerResponseAESKeyIvRSASignVerifyEl.click(function (e) {
                    let aesKey = that.serverResponseAESKeyEL.val();
                    let aesKeyRsaSign = that.serverResponseAESKeyRSASignEL.val();
                    let aesIv = that.serverResponseAESIvEL.val();
                    let aesIvRsaSign = that.serverResponseAESIvRSASignEL.val();
                    if (!aesKey || !aesKeyRsaSign || !aesIv || !aesIvRsaSign) return;
                    let rsa = new RSA();
                    let aesKeyRsaSignRes = rsa.signVerify(aesKey, aesKeyRsaSign, KEY.serverPublicKey);
                    that.serverResponseAESKeyRSASignVerifyEL.html(aesKeyRsaSignRes ? "true" : "false");
                    let aesIvRsaSignRes = rsa.signVerify(aesIv, aesIvRsaSign, KEY.serverPublicKey);
                    that.serverResponseAESIvRSASignVerifyEL.html(aesIvRsaSignRes ? "true" : "false");
                });

                // 服务端响应的AES密文进行解密
                that.btnServerResponseAESDecryptEl.click(function (e) {
                    let aesKey = that.serverResponseAESKeyEL.val();
                    let aesIv = that.serverResponseAESIvEL.val();
                    let aesData = that.serverResponseAESEncryptedEl.val();
                    if (!aesKey || !aesIv || !aesData) return;
                    let aes = new AES(aesKey, aesIv);
                    let decrypted = aes.decrypt(aesData);
                    that.serverResponseAESDecryptedEL.val(decrypted);
                });

            }

        }

        $(doc).on("click", ".demo-tab-item", function (e) {
            let itemEl = $(this);
            let demoClass = `demo-${itemEl.data("for")}`;
            $(".demo-tab-item").removeClass("active");
            $(".demo").removeClass("active");
            $(this).addClass("active");
            $(`.demo.${demoClass}`).addClass("active");
        });

        $(doc).ready(function () {
            let key = "abcdef1234567890";
            let iv = "0987654321fedcba";

            // AES
            new AESJS(key, iv);
            new AESPHP(key, iv);
            new AESJSEncrytPHPDecrypt(key, iv);
            new AESPHPEncrytJSDecrypt(key, iv);

            // RSA
            new RSAJS();
            new RSAJSSign();
            new RSAPHP();
            new RSAPHPSign();
            new RSAJSEncrytPHPDecrypt();
            new RSAPHPEncrytJSDecrypt();
            new RSAJSSignPHPVerify();
            new RSAPHPSignJSVerify();

            // AES+RSA
            new AESRSA();
        });
    })(window, document, jQuery);
</script>
</body>
</html>